package com.dong.ui.component.home;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.dong.common.pojo.ResultVO;
import com.dong.common.util.RequestUtils;
import com.dong.common.view.CommonView;
import com.dong.module.foodmenu.pojo.FoodMenu;
import com.dong.ui.component.IconPanel;
import com.dong.ui.constant.RouterConst;
import com.dong.ui.util.MessageUtils;
import com.dong.ui.util.RouterUtils;
import sun.rmi.runtime.Log;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @description:
 * @author: 陈瑞东
 * @create: 2021-08-27 10:10
 */
public class FoodListPanel extends JPanel implements CommonView {
    JPanel jp = this;
    /*==================组件==================*/
    private JPanel topPanel;
    private JPanel bottomPanel;
    private JScrollPane bottomScrollPane;

    private JTextField searchTextField;
    private JButton searchButton;

    private JPopupMenu foodPopupMenu; // 食物右键菜单
    private JMenu operationMenu;
    private JMenuItem updateItem;
    private JMenuItem removeItem;

    private JMenuItem logItem;

    /*==================组件==================*/
    /*==================参数==================*/
    private int iconHeight = 200;
    private int iconWidth = 200;

    private List<FoodMenu> data;
    // 当前页码
    private int current;
    // 每页数据
    private int size;
    // 搜索参数
    private String name;

    // 下方面板垂直滚动条宽度
    private int bottomScrollPaneVBarWidth;
    // 下方面板宽度
    private int bottomScrollPaneWidth;
    // 下方面板高度
    private int bottomScrollPaneHeight;

    // 选中菜单的id
    private String selectId;
    // 选中菜单的名字
    private String selectName;

    // 操作菜单项的名字
    private static final String OPERATION_MENU_NAME = "操作 ";
    // 更新菜单项的名字
    private static final String UPDATE_ITEM_NAME = "修改";
    // 删除菜单项的名字
    private static final String REMOVE_ITEM_NAME = "删除";
    // 日志菜单项的名字
    private static final String LOG_ITEM_NAME = "日志";



    /*==================参数==================*/
    /*==================标志==================*/
    private boolean requestFlag = true;

    private boolean endFlag = false; // 数据到底标志
    /*==================标志==================*/

    public FoodListPanel() {
        init(null);
    }

    public FoodListPanel(LayoutManager layout) {
        super(layout);
        init(null);
    }

    @Override
    public void init(Map<String, Object> params) {
        setBackground(Color.white);

        handleView();

        // 设置可见
        setVisible(true);

        handleAction();
    }


    @Override
    public void initComponent() {
        topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        topPanel.setOpaque(false);
        topPanel.setBorder(BorderFactory.createRaisedSoftBevelBorder());

        searchTextField = new JTextField(20);
        searchButton = new JButton("搜索");

        bottomPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
        bottomPanel.setOpaque(false);

        bottomScrollPane = new JScrollPane(bottomPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        // 设置滚动条单次滚动间距（滚动速度）
        bottomScrollPane.getVerticalScrollBar().setUnitIncrement(20);
        bottomScrollPane.setOpaque(false);
        bottomScrollPane.getViewport().setOpaque(false);

        // 设置右键弹出菜单
        foodPopupMenu = new JPopupMenu();
        operationMenu = new JMenu(OPERATION_MENU_NAME);
        updateItem = new JMenuItem(UPDATE_ITEM_NAME);
        removeItem = new JMenuItem(REMOVE_ITEM_NAME);

        logItem = new JMenuItem(LOG_ITEM_NAME);
    }

    @Override
    public void initParams() {
        bottomScrollPaneVBarWidth = 0;
        bottomScrollPaneWidth = iconWidth * 4;
        bottomScrollPaneHeight = iconHeight * 2;

        resetParams();
        fillOnePageData();
    }

    /**
     * 填充一页图标的数据
     * @return
     */
    private void fillOnePageData() {
        int colCount = (bottomScrollPaneWidth - bottomScrollPaneVBarWidth) / iconWidth;
        int rowCount = (bottomScrollPaneHeight - 1) / iconHeight + 1;
        int firstNum = colCount * rowCount;
        firstNum = firstNum % size == 0 ? firstNum : firstNum + 1;
        while (!endFlag && data.size() < firstNum) {
            requestList(current, size);
        }
    }

    /**
     * 重置参数
     */
    private void resetParams() {
        current = 1;
        size = 10;
        name = "";
        data = new ArrayList<>();
        endFlag = false;
    }

    @Override
    public void handleView() {
        initParams();
        initComponent();

        // 组装右键弹出菜单
        operationMenu.add(updateItem);
        operationMenu.add(removeItem);
        foodPopupMenu.add(operationMenu);
        foodPopupMenu.add(logItem);

        Box searchBox = Box.createHorizontalBox();

        searchBox.add(searchTextField);
        searchBox.add(Box.createHorizontalStrut(5));
        searchBox.add(searchButton);

        topPanel.add(searchBox);

        reFlushDataView();

        // 添加上下容器
        this.add(topPanel, BorderLayout.NORTH);
        this.add(bottomScrollPane);
    }

    @Override
    public void handleAction() {
        // 上部分点击搜索按钮事件
        searchButtonClickEvent();
        // 下部分容器大小改变事件
        bottomScrollPaneResizeEvent();
        // 下部分容器滚动条触底事件
        bottomScrollPaneBarToBottomEvent();
        // 弹出菜单选项选中事件
        popupMenuItemClickEvent();
    }

    /**
     * 弹出菜单选项选中事件
     */
    private void popupMenuItemClickEvent() {
        ActionListener menuItemListener = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // 先判断id是否选中
                if (StringUtils.isBlank(selectId)) {
                    MessageUtils.showMessageDialog(jp, "未选中菜单", "提示", JOptionPane.WARNING_MESSAGE);
                    return;
                }
                String command = e.getActionCommand();
                switch (command) {
                    case UPDATE_ITEM_NAME:
                        updateMenuEvent();
                        break;
                    case REMOVE_ITEM_NAME:
                        // 删除菜单操作
                        removeMenuEvent();
                        break;
                    case LOG_ITEM_NAME:
                        // 弹出日志页面
                        Map<String, Object> params = new HashMap<String, Object>() {{
                            put("id", selectId);
                        }};
                        RouterUtils.router(RouterConst.VIEW_FOODLOG, params);
                    default:
                }
            }
        };

        updateItem.addActionListener(menuItemListener);
        removeItem.addActionListener(menuItemListener);
        logItem.addActionListener(menuItemListener);
    }

    /**
     * 更新菜单操作
     */
    private void updateMenuEvent() {
        Map<String, Object> params = new HashMap<String, Object>() {{
            put("parentPanel", jp);
            put("id", selectId);
        }};
        RouterUtils.router(RouterConst.VIEW_ADDFOOD, params);
    }

    /**
     * 删除菜单操作
     */
    private void removeMenuEvent() {
        int option = MessageUtils.showConfirmDialog(this, "是否要删除菜单【" + selectName + "】？", "删除菜单", JOptionPane.YES_NO_OPTION);
        if (option == JOptionPane.YES_OPTION) {
            requestBegin();
            Map<String, Object> params = new HashMap<String, Object>() {{
                put("id", selectId);
            }};
            ResultVO<Void> result = (ResultVO<Void>) RequestUtils.sendRequest("food/delete", params);
            requestEnd();
            if (result.isSuccess()) {
                MessageUtils.showMessageDialog(jp, "删除成功！", "成功", JOptionPane.INFORMATION_MESSAGE);
                // 刷新页面
                flushPage();
            } else {
                MessageUtils.showMessageDialog(jp, result.getMessage(), "失败", JOptionPane.INFORMATION_MESSAGE);
            }
        }
    }

    /**
     * 点击搜索按钮事件
     */
    private void searchButtonClickEvent() {
        searchButton.addActionListener(e -> {
            flushPage();
        });
    }

    /**
     * 刷新页面
     */
    private void flushPage() {
        // 滚动条置顶
        bottomScrollPane.getVerticalScrollBar().setValue(0);
        resetParams();
        this.name = searchTextField.getText();
        // 填充一页数据
        fillOnePageData();
        reFlushDataView();
    }

    /**
     * 添加新数据后的操作
     */
    public void requestNewRecord() {
        resetParams();
        // 填充一页数据
        fillOnePageData();
        reFlushDataView();
    }

    /**
     * 下部分容器滚动条触底事件
     */
    private void bottomScrollPaneBarToBottomEvent() {
        bottomScrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
            @Override
            public void adjustmentValueChanged(AdjustmentEvent e) {
                Object source = e.getSource();
                if (source instanceof JScrollBar) {
                    int nowPoint = ((JScrollBar) source).getValue();
                    int barHeight = ((JScrollBar) source).getHeight();
                    int maxHeight = ((JScrollBar) source).getMaximum();
                    // 滚动条在距离底部20的位置的时候读取新数据
                    if (nowPoint + barHeight >= maxHeight - 20) {
                        if (!endFlag) {
                            requestList(current, size);
                            reFlushDataView();
                        }
                    }
                }
            }
        });
    }

    /**
     * 下部分容器大小改变事件
     */
    private void bottomScrollPaneResizeEvent() {
        bottomScrollPane.addComponentListener(new ComponentAdapter() {

            @Override
            public void componentResized(ComponentEvent e) {
                bottomScrollPaneWidth = bottomScrollPane.getWidth();
                bottomScrollPaneHeight = bottomScrollPane.getHeight();
                bottomScrollPaneVBarWidth = bottomScrollPane.getVerticalScrollBar().getWidth();
                updateScrollSize();
            }

        });
    }

    /**
     * 修改滚动窗口尺寸
     */
    private void updateScrollSize() {
        // 计算宽度
        int width = bottomScrollPaneWidth - bottomScrollPaneVBarWidth;

        int colCount = width / iconWidth;
        int rowCount = (data.size() - 1) / colCount + 1;
        // 计算高度
        int height = iconHeight * rowCount;

        bottomPanel.setPreferredSize(new Dimension(width, height));
        bottomPanel.updateUI();
    }


    /**
     * 请求参数
     */
    private void requestList(int current, int size) {
        if (!this.requestFlag) {
            return;
        }
        requestBegin();


        Map<String, Object> params = new HashMap<String, Object>() {{
            put("current", current);
            put("size", size);
            put("name", name);
        }};
        // 发起请求
        ResultVO<List<FoodMenu>> resultVO = (ResultVO<List<FoodMenu>>) RequestUtils.sendRequest("food/list", params);
        if (resultVO.isSuccess()) {
            // 获取成功
            if (resultVO.getData().isEmpty()) {
                endFlag = true;
            } else {
                this.data.addAll(resultVO.getData());
                this.current++;
            }
        } else {
            // 获取失败
            MessageUtils.showMessageDialog(this, resultVO.getMessage(), "失败", JOptionPane.INFORMATION_MESSAGE);
        }

        requestEnd();
    }

    /**
     * 请求开始
     */
    private void requestBegin() {
        // 设置鼠标图标为加载图标
        this.setCursor(new Cursor(Cursor.WAIT_CURSOR));
        // 设置不能登录
        this.requestFlag = false;
    }

    /**
     * 请求结束
     */
    private void requestEnd() {
        // 还原鼠标图标
        this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
        // 设置可以登录
        this.requestFlag = true;
    }

    /**
     * 刷新数据显示
     */
    private void reFlushDataView() {
        this.bottomPanel.removeAll();
        for (FoodMenu item : data) {
//            String path = FoodListPanel.class.getClassLoader().getResource(".").getPath() + "/" + item.getImage();
            String path = item.getImage();
            IconPanel iconPanel = new IconPanel(item.getId(), item.getName(), new ImageIcon(path), new Dimension(iconWidth, iconHeight));
            // 给图标面板添加右键事件
            iconPanelMouseEvent(iconPanel);
            bottomPanel.add(iconPanel);
        }
        updateScrollSize();
    }

    /**
     * 图标面板的鼠标事件
     * @param iconPanel
     */
    private void iconPanelMouseEvent(IconPanel iconPanel) {
        iconPanel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {
                // 设置选中目标
                selectId = iconPanel.getId();
                selectName = iconPanel.getText();
                if (e.isPopupTrigger()) {
                    foodPopupMenu.show(iconPanel, e.getX(), e.getY());
                    return;
                }
                // 左键事件
                if (e.getButton() == MouseEvent.BUTTON1) {
                    // 弹出详情页
                    Map<String, Object> params = new HashMap<String, Object>() {{
                        put("id", selectId);
                    }};
                    RouterUtils.router(RouterConst.VIEW_FOODDETAIL, params);
                }
            }
        });
    }
}
